﻿using System;
using System.Collections.Generic;

using UnityEngine;
using UnityEngine.UI;


public abstract class UIViewBase : MonoBehaviour,IUIView
{
    private readonly Dictionary<string, Component> _componentCache = new Dictionary<string, Component>();
    private int? _originalLayer; // 记录原始Layer

    /// <summary>
    /// 生命周期：实例化后首次调用
    /// </summary>
    public virtual void OnCreate() { }

    /// <summary>
    /// 生命周期：界面显示时调用
    /// </summary>
    public virtual void OnShow() { }

    /// <summary>
    /// 生命周期：界面隐藏时调用
    /// </summary>
    public virtual void OnHide() { }

    public virtual void OnClose()
    {
        if (ViewModel != null)
            ViewModel.PropertyChanged -= OnViewModelPropertyChanged;
    }

    /// <summary>
    /// 通过路径和类型绑定UI组件
    /// </summary>
    protected T BindComponent<T>(string path) where T : Component
    {
        if (_componentCache.TryGetValue(path, out var comp))
        {
            return comp as T;
        }

        var child = transform.Find(path);
        if (child == null)
        {
            Debug.LogWarning($"未找到路径: {path}");
            return null;
        }

        var component = child.GetComponent<T>();
        if (component == null)
        {
            Debug.LogWarning($"在路径 {path} 上未找到组件: {typeof(T).Name}");
            return null;
        }

        _componentCache[path] = component;
        return component;
    }

    /// <summary>
    /// 实例化指定类型的UIView
    /// </summary>
    public static T InstantiateView<T>() where T : UIViewBase
    {
        var type = typeof(T);
        var attribute = (ViewPathAttribute)Attribute.GetCustomAttribute(type, typeof(ViewPathAttribute));
        if (attribute == null)
        {
            Debug.LogError($"未找到 ViewPathAttribute 特性，请为 {type.Name} 设置路径！");
            return null;
        }

        var prefab = Resources.Load<T>(attribute.Path);
        if (prefab == null)
        {
            Debug.LogError($"未找到路径 {attribute.Path} 的预制体！");
            return null;
        }

        var instance = Instantiate(prefab);
        instance.OnCreate();
        return instance;
    }

    /// <summary>
    /// 通过层级控制显示/隐藏和射线检测，并支持恢复原始Layer
    /// </summary>
    public virtual void SetVisibleByLayer(bool visible)
    {
        const string invisibleLayerName = "InvisibleUI";
        int invisibleLayer = LayerMask.NameToLayer(invisibleLayerName);
        if (invisibleLayer == -1)
        {
            Debug.LogError("请在Unity中添加名为 InvisibleUI 的Layer！");
            return;
        }

        if (visible)
        {
            // 恢复原始Layer
            if (_originalLayer.HasValue)
            {
                SetLayerRecursively(gameObject, _originalLayer.Value);
                _originalLayer = null;
            }
            OnShow();
        }
        else
        {
            // 记录原始Layer，仅记录一次
            if (!_originalLayer.HasValue)
                _originalLayer = gameObject.layer;
            SetLayerRecursively(gameObject, invisibleLayer);
            OnHide();
        }

        // 控制Canvas和射线检测
        var canvas = GetComponent<Canvas>();
        if (canvas != null)
            canvas.enabled = visible;

        var raycaster = GetComponent<GraphicRaycaster>();
        if (raycaster != null)
            raycaster.enabled = visible;
    }

    /// <summary>
    /// 递归设置Layer
    /// </summary>
    private void SetLayerRecursively(GameObject obj, int layer)
    {
        obj.layer = layer;
        foreach (Transform child in obj.transform)
        {
            SetLayerRecursively(child.gameObject, layer);
        }
    }
    public virtual void BindViewModel(ViewModelBase viewModel)
    {
        ViewModel = viewModel;
        // 订阅 ViewModel 属性变化事件
        ViewModel.PropertyChanged += OnViewModelPropertyChanged;
    }

    private void OnViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        // 子类重写，根据属性名刷新 UI
    }

    public ViewModelBase ViewModel { get; private set; }
    protected virtual void OnDestroy()
    {
        OnClose();
    }
}